// 
// 複数のモデルを同一円周上に配置して、スワイプでモデルの表示位置を回転させるサンプルです。
// 
// RSSample by Selphy, Kiroru Inc. is licensed under a Creative Commons 表示 - 非営利 - 継承 3.0 非移植 License .
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// 
// author selphy
// 

// バージョン
#pragma version(1)

// パッケージ
#pragma rs java_package_name(jp.kiroru_inc.rs_sample)

#include "rs_graphics.rsh"
#include "rs_cl.rsh"

// ---------------------------------------------
//                  定数
// ---------------------------------------------
static const int32_t MODEL_COUNT = 3;
static const float VALUE_PI = 3.141592653f;
static const float VALUE_DOUBLE_PI = VALUE_PI * 2;
static const int32_t ACTION_DOWN = 0;
static const int32_t ACTION_UP = 1;
static const int32_t ACTION_MOVE = 2;

// ---------------------------------------------
//                  構造体
// ---------------------------------------------
typedef struct RS_Droid {
    rs_allocation texture;
} RS_Droid_t;

// ---------------------------------------------
//                  変数
// ---------------------------------------------
RS_Droid_t *gDroids;

rs_program_vertex gProgVertex;
rs_program_store gProgStoreBlendAlpha;
rs_program_fragment gProgFragmentTexture;
rs_program_raster gCullNone;

float2 gTouchPoint;
float2 gSwipePoint;
int32_t gRotX;


/* ------------------------------------------- */
/* Java側のタッチイベントから座標を受け取ります。       */
/* ------------------------------------------- */
void setTouchPosition(int32_t action, float2 position) {
    switch (action) {
    case ACTION_DOWN:
        gTouchPoint = position;
        break;
    case ACTION_UP:
        break;
    case ACTION_MOVE:
        gSwipePoint += position - gTouchPoint;
        gTouchPoint = position;
        break;
    default:
        return;
    }
}

/* ------------------------------------------- */
/* メインループです。                              */
/* ------------------------------------------- */
int32_t root() {
    rsgClearColor(0.0f, 0.0f, 0.0f, 1.0f);      // RGBA
    rsgClearDepth(1.0f);
    
    // プロジェクション設定
    rs_matrix4x4 proj;
    rsMatrixLoadPerspective(&proj, 30.0f, (float) rsgGetWidth() / (float) rsgGetHeight(), 0.01f, 1000.0f);
    rsgProgramVertexLoadProjectionMatrix(&proj);
    
    rsgBindProgramStore(gProgStoreBlendAlpha);
    rsgBindProgramFragment(gProgFragmentTexture);
    
    // モデル座標の回転を計算
    if (gSwipePoint.x != 0) {
        gRotX += gSwipePoint.x * 0.5f;
        gSwipePoint.xy = 0;
        if (gRotX > 360 || gRotX < -360)
            gRotX %= 360;
    }
    
    // モデル座標
    rs_matrix4x4 matrix;
    rsMatrixLoadIdentity(&matrix);
    rsMatrixLoadTranslate(&matrix, 0, 0, -500);
    rsMatrixRotate(&matrix, 30, 1, 0, 0);
    rsMatrixRotate(&matrix, gRotX, 0, 1, 0);
    rsgProgramVertexLoadModelMatrix(&matrix);
    
    float x, y, z, minX, minY, maxX, maxY;
    
    rsgBindProgramRaster(gCullNone);
    
    // テクスチャー描画
    for (int32_t i=0; i<MODEL_COUNT; i++) {
        RS_Droid_t droid = gDroids[i];
        float rad = VALUE_DOUBLE_PI * (float) i / (float) MODEL_COUNT;
        x = 50 * sin(rad);
        y = 0;
        z = 50 * cos(rad);
        
        minX = z * sin(rad - VALUE_DOUBLE_PI) + x * cos(rad - VALUE_DOUBLE_PI) - 25;
        maxX = minX + 50;
        minY = y - 25;
        maxY = minY + 50;
        z = z * cos(rad - VALUE_DOUBLE_PI) - x * sin(rad - VALUE_DOUBLE_PI);
        
        rsgBindTexture(gProgFragmentTexture, 0, droid.texture);
        rsgDrawQuadTexCoords(minX, maxY, z, 0.f, 0.f,
                             minX, minY, z, 0.f, 1.f,
                             maxX, minY, z, 1.f, 1.f,
                             maxX, maxY, z, 1.f, 0.f);   
    }
    
    // 20fps
    return 50;
}